/* 
 * Advanced Foundation Classes
 * Copyright (C) 2000/2004  Fabio Rotondo - Andrea Galimberti
 *  
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *  
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *  
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */
#include "context.h"

static int afc_easygui_int_context_del_widget ( void * dc );
static void afc_easygui_widget_event_key_press ( GtkWidget * w, GdkEventKey * key, DynamicClass * dc );
static void afc_easygui_widget_event_key_release ( GtkWidget * w, GdkEventKey * key, DynamicClass * dc );
static void afc_easygui_context_internal_popup_position ( GtkMenu * menu, gint * px, gint * py, gboolean * push_in, gpointer data );
static int afc_easygui_context_internal_build ( EasyGUIContext * context );
static EasyGUIWidgetData * afc_easygui_internal_widget_data_new ( EasyGUIContext * context );

static const char class_name []  = "EasyGUI Context";

// {{{ afc_easygui_context_new ( egui, context_name ) *******
EasyGUIContext * afc_easygui_context_new ( EasyGUI * easygui, const char * context_name )
{
TRY ( EasyGUIContext * )

	F_IN()

	char buf [ 50 ];
	EasyGUIContext * context;

	if ( ( context = afc_malloc ( sizeof ( EasyGUIContext ) ) ) == NULL ) RAISE_FAST_RC ( AFC_ERR_NO_MEMORY, "context", NULL );

	afc_dprintf ( "%s: New Context: %p\n", __FUNCTION__, context );

	if ( context_name  == NULL )
	{
		sprintf ( buf, "%d", ( int ) context );
		context->name = afc_string_dup ( buf );
	} else
		context->name = afc_string_dup ( context_name );

	if ( ( context->containers = afc_nodemaster_new () ) == NULL ) RAISE_FAST_RC ( AFC_ERR_NO_MEMORY, "containers", NULL );
	afc_dprintf ( "%s: Containers: %p\n", __FUNCTION__, context->containers );

	if ( ( context->widgets = afc_dictionary_new () ) == NULL ) RAISE_FAST_RC ( AFC_ERR_NO_MEMORY, "widgets", NULL );

	afc_dictionary_set_clear_func ( context->widgets, afc_easygui_int_context_del_widget );
	afc_dprintf ( "%s: Widgets: %p\n", __FUNCTION__, context->widgets );

	if ( ( context->radiogroups = afc_dictionary_new () ) == NULL )  RAISE_FAST_RC ( AFC_ERR_NO_MEMORY, "radio groups", NULL );
	afc_dprintf ( "%s: Radios: %p\n", __FUNCTION__, context->radiogroups );

	if ( ( context->menus = afc_dictionary_new () ) == NULL ) RAISE_FAST_RC ( AFC_ERR_NO_MEMORY, "menus", NULL );
	afc_dprintf ( "%s: menus: %x\n", __FUNCTION__, ( int ) context->menus );

	context->egui = easygui;

	RETURN ( context );

EXCEPT
	afc_dprintf ( "EXCEPTION!\n" );
	afc_easygui_context_del ( context );
	context = NULL;

FINALLY

ENDTRY
}
// }}}

int afc_easygui_context_delete ( EasyGUIContext * context )
{
	if ( context == NULL ) return ( AFC_ERR_NO_ERROR );
	return ( afc_dictionary_del_item ( context->egui->contexts, context->name ) );
}

// {{{ afc_easygui_widget_set_attrs ( context, widget_name, ... )
/*
@node afc_easygui_widget_set_attrs

       NAME: afc_easygui_widget_set_attrs - Sets one or more attributes of a widget instance

   SYNOPSIS: int afc_easygui_widget_set_attrs ( EasyGUIContext * context, char * wname, ... )

DESCRIPTION: this function is used to set one or more attributes of a widget instance.
The /wname/ parameter is the name of the widget to be modified, and it is followed by a
series of attribute name, attribute value pairs. The series *must* be ended with the
AFC_TAG_END tag.

For example:
afc_easygui_widget_set_attrs ( easygui, "mylabel", AFC_EASYGUI_ATTR_CAPTION, "foobar", AFC_TAG_END )

      INPUT: - context - pointer to a valid EasyGUI Context instance;
             - wname - name of the widget whose attributes should be altered;
             - ... - series of attribute name, attribute value pairs, ended by the AFC_TAG_END tag.

    RESULTS: - AFC_EASYGUI_ERR_WIDGET_UNKNOWN if the specifed widget has not been found;
             - AFC_EASYGUI_ERR_NO_CLASS if the class to which the widget belongs couldn't
               be determined.

@endnode
*/
int afc_easygui_widget_set_attrs ( EasyGUIContext * context, char * wname, ... )
{
	va_list tags;
	DynamicClass * dyn = NULL;
	int afc_res = AFC_ERR_NO_ERROR;

	F_IN()

	if ( context == NULL ) return ( AFC_LOG_FAST ( AFC_ERR_NULL_POINTER ) );

	if ( ( dyn = afc_dictionary_get ( context->widgets, wname ) ) == NULL )
		return ( AFC_LOG ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_WIDGET_UNKNOWN, "Unkown widget", wname ) );
	
	va_start ( tags, wname );

	afc_res = afc_dynamic_class_execute_vars ( dyn, "set_attrs", tags );

	va_end ( tags );
	
	F_OUT()

	return ( afc_res );
}
// }}}
// {{{ afc_easygui_widget_get_attr ( context, wname, attr, buffer )
/*
@node afc_easygui_widget_get_attr

       NAME: afc_easygui_widget_get_attr - Retrieves a widget attribute

   SYNOPSIS: int afc_easygui_widget_get_attr ( EasyGUIContext * context, char * wname, int attr, void * buffer )

DESCRIPTION: this function retrieves the value of a widget's attribute.
The value of the attribute /attr/ is copied in the /buffer/ parameter.

      INPUT: - context - pointer to a valid EasyGUI Context instance;
             - wname - name of the widget to be queried for the attribute;
             - attr - name of the attribute;
             - buffer - area in which to copy the attribute's value.

    RESULTS: - AFC_EASYGUI_ERR_WIDGET_UNKNOWN if the specifed widget has not been found;
             - AFC_EASYGUI_ERR_NO_CLASS if the class to which the widget belongs couldn't
               be determined;

@endnode
*/
int afc_easygui_widget_get_attr ( EasyGUIContext * context, char * wname, int attr, void * buffer )
{
	DynamicClass * dyn = NULL;
	int afc_res = AFC_ERR_NO_ERROR;

	F_IN()

	if ( context == NULL ) return ( AFC_LOG_FAST ( AFC_ERR_NULL_POINTER ) );

	if ( ( dyn = afc_dictionary_get ( context->widgets, wname ) ) == NULL )
		return ( AFC_LOG ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_WIDGET_UNKNOWN, "Unknown widget", wname ) );

	afc_res = afc_dynamic_class_execute ( dyn, "get_attr", attr, buffer, AFC_DYNAMIC_CLASS_ARG_END );

	F_OUT()

	return ( afc_res );
}
// }}}
// {{{ afc_easygui_widget_set_attr ( context, wname, attr, val )
/*
@node afc_easygui_widget_set_attr

       NAME: afc_easygui_widget_set_attr - Sets an attribute value of a widget

   SYNOPSIS: int afc_easygui_widget_set_attr ( EasyGUI * easygui, char * wname, int attr, void * val )

DESCRIPTION: This function sets the value of a widget's attribute.

      INPUT: - context - pointer to a valid EasyGUIContext instance;
             - wname - name of the widget to be queried for the attribute;
             - attr - name of the attribute;
             - val - value of the attribute

    RESULTS: - AFC_EASYGUI_ERR_WIDGET_UNKNOWN if the specifed widget has not been found;
             - AFC_EASYGUI_ERR_NO_CLASS if the class to which the widget belongs couldn't
               be determined;

   SEE ALSO: - afc_easygui_widget_get_attr ()
	     - afc_easygui_widget_get_attrs ()
@endnode
*/
int afc_easygui_widget_set_attr ( EasyGUIContext * context, char * wname, int attr, void * buffer )
{
	DynamicClass * dyn = NULL;
	int afc_res = AFC_ERR_NO_ERROR;

	F_IN()

	if ( context == NULL ) 
		return ( AFC_LOG_FAST ( AFC_ERR_NULL_POINTER ) );

	if ( ( dyn = afc_dictionary_get ( context->widgets, wname ) ) == NULL )
		return ( AFC_LOG ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_WIDGET_UNKNOWN, "Unknown widget", wname ) );

	afc_res = afc_dynamic_class_execute ( dyn, "set_attr", attr, buffer, AFC_DYNAMIC_CLASS_ARG_END );

	F_OUT()

	return ( afc_res );
}
// }}}
// {{{ afc_easygui_widget_add_default_events ( context, dyn, w ) ***
// Adds the default events to the current widget.
// This is needed because some widgets may have, for example, the "keypress" and "keyrelease" event
// and we add them automatically in each widget
int afc_easygui_widget_add_default_events ( EasyGUIContext * context, DynamicClass * dc, GtkWidget * w )
{
	EasyGUIDefaultParams * pars = context->egui->def_params;
	int res;

	F_IN()

	// KeyEvents are selected
	if ( ( pars->key_events )  )
	{
		// We add the events to the widget
		if ( ( res = afc_easygui_widget_connect_signal ( dc, w, "key_press_event", pars->key_events, NULL, (GtkSignalFunc) afc_easygui_widget_event_key_press ) ) != AFC_ERR_NO_ERROR )
			return ( res );

		if ( ( res = afc_easygui_widget_connect_signal ( dc, w, "key_release_event", pars->key_events, NULL, (GtkSignalFunc) afc_easygui_widget_event_key_release ) ) != AFC_ERR_NO_ERROR )
			return ( res );
	}

	F_OUT()
	
	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_widget_execute ( context, wname, method, ... )
/*
@node afc_easygui_widget_execute

       NAME: afc_easygui_widget_execute

   SYNOPSIS: int afc_easygui_widget_execute ( EasyGUIContext * context, char * name, char * method, ... )

DESCRIPTION: executes a method on the widget with name /name/.

      INPUT: - context - pointer to a valid EasyGUI Context instance;
             - name - name of the widget to be acted upon;
             - method - name of the method to be executed;
             - ... - parameters to be passed to the method: the list *must* be closed by
                     AFC_EASYGUI_ARG_END

    RESULTS: - the error (if any) returned by the method executed;
             - AFC_EASYGUI_ERR_WIDGET_UNKNOWN if the specified widget has not been found.

@endnode
*/
int afc_easygui_widget_execute ( EasyGUIContext * context, char * wname, char * method, ... )
{
	va_list args;
	int afc_res;
	DynamicClass * dc = afc_dictionary_get ( context->widgets, wname );

	F_IN()

	if ( dc == NULL )
		return ( AFC_LOG ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_WIDGET_UNKNOWN, "Unknown widget", wname ) );

	va_start ( args, method );

	afc_res = afc_dynamic_class_execute_vars ( dc, method, args );

	va_end ( args );

	F_OUT()

	return ( afc_res );
}
// }}}
// {{{ afc_easygui_context_get_widget ( context, wname ) ****
// Returns the widget corresponding to the given name

// NOTE: this function is actually a macro!

// }}}
// {{{ afc_easygui_context_show_menu ( context, dc, menu_name ) ***
int afc_easygui_context_show_menu ( EasyGUIContext * context, DynamicClass * dc, char * menu_name )
{
	GtkWidget * menu = afc_dictionary_get ( context->menus, menu_name );
	
	F_IN()

	if ( menu == NULL ) return ( AFC_EASYGUI_ERR_MENU_NOT_FOUND );

	gtk_widget_show_all ( GTK_WIDGET ( menu ) );

	if ( dc != NULL )
		gtk_menu_popup ( GTK_MENU ( menu ), NULL, NULL, afc_easygui_context_internal_popup_position, dc, 1, 0 );
	else
		gtk_menu_popup ( GTK_MENU ( menu ), NULL, NULL, NULL, NULL, 1, 0 );

	F_OUT()

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_widget_store_function ( context, dyn, event, func_name ) *****
int afc_easygui_widget_store_function ( EasyGUIContext * context, DynamicClass * dyn, const char * event, const char *  func_name )
{
	gpointer func;

	F_IN()
	
	if ( func_name == NULL ) return ( AFC_ERR_NO_ERROR );

	// Attemps to get the right symbol pointer for the given function name
	if ( g_module_symbol ( context->egui->int_data->local, func_name, ( gpointer * ) &func ) == FALSE ) 
		return ( AFC_LOG ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_SYMBOL_UNKNOWN, "Unknown sybol", func_name ) );

	// Store the function pointer inside the DynamicClass Private Vars
	if ( dyn->private_vars == NULL )
		if ( ( dyn->private_vars = afc_dictionary_new () ) == NULL )
			return ( AFC_LOG_FAST_INFO ( AFC_ERR_NO_MEMORY, "private_vars" ) );

	afc_dictionary_set ( dyn->private_vars, event, func );
	
	F_OUT()

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_widget_get_horient ( context, horient ) ****
int afc_easygui_widget_get_horient ( EasyGUIContext * context, char * horient )
{
	if ( horient == NULL ) return ( AFC_EASYGUI_HORIENT_RIGHT );

	if ( strcasecmp ( horient, "LEFT" ) == 0 )   return ( AFC_EASYGUI_HORIENT_LEFT );
	if ( strcasecmp ( horient, "TOP" ) == 0 )    return ( AFC_EASYGUI_HORIENT_TOP );
	if ( strcasecmp ( horient, "BOTTOM" ) == 0 ) return ( AFC_EASYGUI_HORIENT_BOTTOM );

	return ( AFC_EASYGUI_HORIENT_RIGHT );
}
// }}}
// {{{ afc_easygui_widget_get_relief ( context, relief ) ***
int afc_easygui_widget_get_relief ( EasyGUIContext * context, char * relief )
{
	if ( relief == NULL ) return ( GTK_RELIEF_NORMAL );

	if ( strcasecmp ( relief, "HALF" ) == 0 )	return ( GTK_RELIEF_HALF );
	if ( strcasecmp ( relief, "NONE" ) == 0 )	return ( GTK_RELIEF_NONE );

	return ( GTK_RELIEF_NORMAL );
}
// }}}
// {{{ afc_easygui_context_set_gui ( context, gui ) ********
/*
@node afc_easygui_set_gui

@endnode
*/
int afc_easygui_context_set_gui ( EasyGUIContext * context, const char * gui)
{
	F_IN()

	if ( context == NULL ) return ( AFC_LOG_FAST ( AFC_ERR_NULL_POINTER ) );
	if ( gui == NULL ) return ( AFC_LOG_FAST ( AFC_ERR_NULL_POINTER ) );

	if ( ( context->gui ) && ( afc_string_max ( context->gui ) < strlen ( gui ) ) )
	{
		afc_string_delete ( context->gui );
		context->gui = afc_string_dup ( gui );
	} else {
		if ( context->gui ) 	afc_string_copy ( context->gui, gui, ALL );	
		else 			context->gui = afc_string_dup ( gui );
	}

	if ( context->gui == NULL ) return ( AFC_LOG_FAST_INFO ( AFC_ERR_NO_MEMORY, "gui" ) );

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_set_gui_from_file ( egui, file_name ) ********
int afc_easygui_context_set_gui_from_file ( EasyGUIContext * context, const char * filename )
{
TRY ( int )

	FILE * fh;
	char * mem = NULL;
	long size;
	int   res;

	F_IN()

	if ( context == NULL ) RAISE_FAST_RC ( AFC_ERR_NULL_POINTER, "context", AFC_ERR_NULL_POINTER );

	if ( ( fh = fopen ( filename, "r" ) ) == NULL )
		RAISE_RC ( AFC_LOG_ERROR, AFC_EASYGUI_ERR_FILE_NOT_FOUND, "Cannot load GUI file", filename, AFC_EASYGUI_ERR_FILE_NOT_FOUND );

	fseek ( fh, 0, SEEK_END );
	size = ftell ( fh );
	fseek ( fh, 0, SEEK_SET );

	if ( ( mem = afc_malloc ( size+1 ) ) == NULL )
		RAISE_FAST_RC ( AFC_ERR_NO_MEMORY, "mem", AFC_ERR_NO_MEMORY );

	fread ( mem, size, 1, fh );
	fclose ( fh );

	res = afc_easygui_context_set_gui ( context, mem );

	RETURN ( res );

EXCEPT

FINALLY
	afc_free ( mem );

ENDTRY
}
// }}}
// {{{ afc_easygui_context_show ( egui ) ***********
/*
@node afc_easygui_show

@endnode
*/
int afc_easygui_context_show ( EasyGUIContext * context )
{
	int afc_res = 0;
	
	F_IN()

	if ( context == NULL ) return ( AFC_ERR_NULL_POINTER );

	_afc_dprintf ( "%s: context: %p\n", __FUNCTION__, context );
	_afc_dprintf ( "%s: win: %p\n", __FUNCTION__, context->win );

	if ( context->win == NULL ) if ( ( afc_res = afc_easygui_context_internal_build ( context ) ) != AFC_ERR_NO_ERROR ) return ( afc_res );

	if ( context->win ) gtk_widget_show_all ( context->win );

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_context_add_container ( egui, w, dc, type, homo )
int afc_easygui_context_add_container ( EasyGUIContext * context, GtkWidget * w, DynamicClass * dc, int type, int homogeneous )
{
	EasyGUIWidgetData * container = NULL;

	if ( context->curr_container ) afc_dynamic_class_execute ( context->curr_container->dc , "add", w, type, AFC_DYNAMIC_CLASS_ARG_END );

	if ( ( container = afc_easygui_internal_widget_data_new ( context ) ) == NULL ) return ( AFC_LOG_FAST_INFO ( AFC_ERR_NO_MEMORY, "container" ) );

	container->gtk_handle 	= w;
	container->type 	= type;
	container->homogeneous 	= homogeneous;
	container->dc  		= dc;

	afc_dynamic_class_set_var ( dc, AFC_DYNAMIC_CLASS_VAR_KIND_POINTER, "ewidget", container );

	context->curr_container = container;
	afc_nodemaster_add ( context->containers, container, AFC_NODEMASTER_ADD_TAIL );

	if (  context->egui->def_params->name != NULL )
	{
		afc_dictionary_set ( context->widgets, context->egui->def_params->name, dc );
		gtk_widget_set_name ( GTK_WIDGET ( container->gtk_handle ), context->egui->def_params->name );
	}

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_context_close_container ( context )
int afc_easygui_context_close_container ( EasyGUIContext * context )
{
	context->curr_container = ( EasyGUIWidgetData * ) afc_nodemaster_del ( context->containers );

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_register_widget ( egui, w, dc )
int afc_easygui_widget_register ( EasyGUIContext * context, GtkWidget * w, DynamicClass * dc )
{
	EasyGUIWidgetData * ewidget;

	if ( ( ewidget = afc_easygui_internal_widget_data_new ( context ) ) == NULL ) return ( AFC_LOG_FAST_INFO ( AFC_ERR_NO_MEMORY, "ewidget" ) );

	ewidget->gtk_handle = w;

	afc_dynamic_class_set_var ( dc, AFC_DYNAMIC_CLASS_VAR_KIND_POINTER, "ewidget", ewidget );

	if ( context->egui->def_params->name != NULL ) 
	{
		afc_dynamic_class_set_var ( dc, AFC_DYNAMIC_CLASS_VAR_KIND_STRING, "egui_name", context->egui->def_params->name );
		afc_dictionary_set ( context->widgets, context->egui->def_params->name, dc );
		if ( ewidget->gtk_handle ) gtk_widget_set_name ( GTK_WIDGET ( ewidget->gtk_handle ), context->egui->def_params->name );
	}

	if ( context->egui->def_params->info != NULL )
		afc_dynamic_class_set_var ( dc, AFC_DYNAMIC_CLASS_VAR_KIND_STRING, "egui_info", context->egui->def_params->info );

	return ( AFC_ERR_NO_ERROR );
}
// }}}

// ====================================================================================
// INTERNAL FUNCTIONS
// ====================================================================================

// {{{ afc_easygui_int_context_del ( context ) ***********
int afc_easygui_context_del ( void * con )
{
	EasyGUIContext * context = con;

	F_IN()

	if ( context == NULL ) return ( AFC_ERR_NO_ERROR );

	afc_dprintf ( "%s: Free Context: %x\n", __FUNCTION__, ( int ) context );
	afc_dprintf ( "%s: widgets: %x\n", __FUNCTION__, ( int ) context->widgets );
	afc_dprintf ( "%s: containers: %x\n", __FUNCTION__, ( int ) context->containers );
	afc_dprintf ( "%s: radiogroups: %x\n", __FUNCTION__, ( int ) context->radiogroups );
	afc_dprintf ( "%s: menus: %x\n", __FUNCTION__, ( int ) context->menus );

	afc_nodemaster_delete ( context->containers );
	afc_dictionary_delete ( context->widgets );
	afc_dictionary_delete ( context->radiogroups );
	afc_dictionary_delete ( context->menus );

	afc_string_delete ( context->gui );
	afc_string_delete ( context->name );

	afc_free ( context );

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_int_context_del_widget ( void * dc )
static int afc_easygui_int_context_del_widget ( void * dc )
{
	EasyGUIWidgetData * ewidget;
	EasyGUI * egui;

	F_IN()

	if ( dc == NULL ) return ( AFC_ERR_NO_ERROR );

	WIDGET_GET_EWIDGET ( dc, ewidget );

	egui = ewidget->egui;

	WIDGET_FREE_EWIDGET ( dc, ewidget );

	afc_dynamic_class_master_delete_instance ( egui->commands, dc );

	return ( AFC_ERR_NO_ERROR );
}
// }}}
// {{{ afc_easygui_context_internal_popup_position ( menu, px, py, push_in, data )
static void afc_easygui_context_internal_popup_position ( GtkMenu * menu, gint * px, gint * py, gboolean  * push_in, gpointer data )
{
	DynamicClass * dc = data;
	GtkRequisition req;
	EasyGUIWidgetData * ewidget;
	gint sw;

	WIDGET_GET_EWIDGET_VOID ( dc, ewidget );

	gtk_widget_show_all ( GTK_WIDGET ( menu ) );

	gtk_widget_size_request ( GTK_WIDGET ( menu ), &req );

	// Gets the origin x,y coordinates of the calling button
	gdk_window_get_origin ( ewidget->gtk_handle->window, px, py );

	*py -= req.height;
	if ( *py < 0 ) *py = 0;

	// Check if it is possible to show the menu on the screen
	// If the width of the menu is going to be out of bounds, we try to
	// adjust it.
	sw = gdk_screen_width ();
	if ( *px + req.width > sw ) *px = ( sw - req.width );

	printf ( "X: %d - Y: %d\n", *px, *py );

	// Manca:
	// button->set_sensitive = TRUE
}
// }}}
// {{{ afc_easygui_context_internal_build ( context )
/*
@node afc_easygui_internal_build

@endnode
*/
static int afc_easygui_context_internal_build ( EasyGUIContext * context )
{

	if ( ( context->gui == NULL ) || ( afc_string_len ( context->gui ) == 0 ) ) return ( AFC_EASYGUI_ERR_NO_GUI );

	// FIXME: lock risorsa cmd parser
	return ( afc_cmd_parser_parse_string ( context->egui->parser, context->gui, context ) );
}
// }}}
// {{{ afc_easygui_internal_widget_data_new
/*
@node afc_easygui_internal_widget_data_new

	DESCRIPTION: instantiates a new EasyGUIWidgetData object.

@endnode
*/
static EasyGUIWidgetData * afc_easygui_internal_widget_data_new ( EasyGUIContext * context )
{
	EasyGUIWidgetData * ewidget = ( EasyGUIWidgetData * ) afc_malloc ( sizeof ( EasyGUIWidgetData ) );

	if ( ewidget == NULL ) 
	{
		AFC_LOG_FAST ( AFC_ERR_NO_MEMORY );
		return ( NULL );
	}

	ewidget->egui = context->egui;
 
	return ( ewidget );
}
// }}}

// -------------------------------------------------------------------------------------------------------------------
// STANDARD EVENT FUNCTIONS
// -------------------------------------------------------------------------------------------------------------------
// {{{ afc_easygui_widget_event_key_press ( w, key, dc )
static void afc_easygui_widget_event_key_press ( GtkWidget * w, GdkEventKey * key, DynamicClass * dc )
{
	EasyGUIKeyFunc	sig;

	// printf ( "Key Press\n" );

      	if ( dc->private_vars )
        	if ( ( sig = ( EasyGUIKeyFunc ) afc_dictionary_get ( dc->private_vars, "key_press_event" ) ) != NULL )  
			sig ( dc, WIDGET_GET_CONTEXT ( dc ), key->keyval, TRUE );

}
// }}}
// {{{ afc_easygui_widget_event_key_release ( w, key, dc )
static void afc_easygui_widget_event_key_release ( GtkWidget * w, GdkEventKey * key, DynamicClass * dc )
{
	EasyGUIKeyFunc	sig;

	// printf ( "Key Release\n" );

      	if ( dc->private_vars )
        	if ( ( sig = ( EasyGUIKeyFunc ) afc_dictionary_get ( dc->private_vars, "key_release_event" ) ) != NULL )  
			sig ( dc, WIDGET_GET_CONTEXT ( dc ), key->keyval, FALSE );
}
// }}}

